﻿-- get the addon namespace
local addon, ns = ...

-- get the config values
local cfg = ns.cfg

-- get the library
local lib = ns.lib

local talenttree

local lastUpdate=0
cfg.Update=nil
local p
local spname,startTime,endTime

local phealth,phealthmax,ppower,ppowermax,ppactiveRegen,pshape

local function Hedd_findclass()
	talenttree = GetSpecialization() or 5 --GetPrimaryTalentTree()
	if lib.classes[cfg.class] and lib.classes[cfg.class][talenttree] then
		cfg.classfound=true
		if lib.clearCfg then
			lib.clearCfg()
		end
		return lib.classes[cfg.class][talenttree]()
	end
	cfg.classfound=nil
	return false
end

lib.basicevents = function()
	local resetcast = function()
		cfg.casting=nil
		cfg.lastspell=nil
		cfg.lastspell2=nil
		cfg.ischanneling=nil
--		cfg.spellcast={}
		cfg.lastspell_time=nil
	end
	
	function Heddevents:UNIT_POWER_FREQUENT(unit,powerType,...)
		if unit=="player" then
			ppower=cfg.power
			cfg.power=UnitPower("player")
			ppowermax=cfg.powermax
			cfg.powermax=UnitPowerMax("player")
			_,ppactiveRegen=GetPowerRegen()
			cfg.pactiveRegen=ppactiveRegen

			if cfg.power~=ppower or cfg.powermax~=ppowermax or cfg.pactiveRegen~=ppactiveRegen then
				cfg.Update=true
			end
			
			if lib.myonpower then lib.myonpower(unit,powerType) end
		end
	end
	
	function Heddevents:UNIT_HEALTH_FREQUENT(unit)
		if unit=="target" then
			phealth=cfg.health
			phealthmax=cfg.healthmax
			cfg.healthmax=UnitHealthMax("target")
			cfg.health=(cfg.healthmax==0) and 100 or hedlib.round(UnitHealth("target")*100/cfg.healthmax,0)

			if cfg.health~=phealth or  cfg.healthmax~=phealthmax then
				cfg.Update=true
			end
		end
		if lib.myonhealthupdate then lib.myonhealthupdate(unit) end
	end
	
	function Heddevents:ACTIONBAR_UPDATE_COOLDOWN()
		for index,name in pairs(cfg.spells) do
			if cfg.spells[index] and not cfg.spells[index].noupdate and lib.UpdateSpellCD(index) then cfg.Update=true end
		end
	end
	
	function Heddevents:SPELL_ACTIVATION_OVERLAY_GLOW_SHOW()
		Heddevents:ACTIONBAR_UPDATE_COOLDOWN()
	end
	
	function Heddevents:ACTIONBAR_UPDATE_STATE()
		Heddevents:ACTIONBAR_UPDATE_COOLDOWN()
	end

	function Heddevents:ACTIONBAR_UPDATE_USABLE()
		Heddevents:ACTIONBAR_UPDATE_COOLDOWN()
	end

	function Heddevents:SPELL_UPDATE_USABLE()
		Heddevents:ACTIONBAR_UPDATE_COOLDOWN()
	end
	
	function Heddevents:UNIT_AURA(unitID)
--		print(unitID)
		if cfg.watchunits[unitID] and UnitExists(unitID) then
			for index,name in pairs(cfg.auras) do
				if cfg.auras[index].unit==unitID and lib.UpdateAura(index) then cfg.Update=true end
			end
			if unitID=="player" then
				Heddevents:ACTIONBAR_UPDATE_COOLDOWN()
				Heddevents:UNIT_POWER_FREQUENT(unitID)
			end
		end
		if lib.myaura then lib.myaura(unitID) end
	end
	
	local targetchange = function()
		cfg.target=UnitClassification("target")
		if UnitLevel("target")<0 then cfg.target="worldboss" end
		--[[
		elite - Elite
		normal - Normal
		rare - Rare
		rareelite - Rare-Elite
		worldboss - World Boss
		]]
	end
	
	function Heddevents:PLAYER_TARGET_CHANGED()
		resetcast()
		Heddevents:UNIT_AURA("target")
		targetchange()
		lib.ComboUpdate()
		Heddevents:UNIT_HEALTH_FREQUENT("target")
		cfg.Update=true
	end

	function Heddevents:PLAYER_REGEN_ENABLED()
		resetcast()
		cfg.Update=true
	end
	
	function Heddevents:PLAYER_EQUIPMENT_CHANGED(slot, hasItem)
		lib.UpdateEquip(slot)
		lib.UpdateSet()
		if lib.myonequip then lib.myonequip() end
	end

	function Heddevents:UNIT_SPELLCAST_START(u,spellname)
		if u=="player" then
			if cfg.debugspells then print(cfg.now.." UNIT_SPELLCAST_START "..spellname) end
			spname, _, _, _, startTime, endTime = UnitCastingInfo(u)
			if not spname then print("spell not found") return end
			cfg.casting=spname
			cfg.castStart=startTime / 1e3
			cfg.castEnd=endTime / 1e3
			if lib.onspellupdate then lib.onspellupdate() end
			if lib.myonspellcaststart then lib.myonspellcaststart(spellname) end
			cfg.Update=true
		end
	end
	
	function Heddevents:UNIT_SPELLCAST_INTERRUPTED(u,spellname)
		if u=="player" then
			if cfg.debugspells then print(cfg.now.." UNIT_SPELLCAST_INTERRUPTED "..spellname) end
			cfg.ischanneling=nil
			cfg.casting=nil
			cfg.castEnd=cfg.now
			if lib.onspellupdate then lib.onspellupdate() end
			if lib.myonspellcastinterrupted then lib.myonspellcastinterrupted(spellname) end
			cfg.Update=true
		end
	end
	
	function Heddevents:UNIT_SPELLCAST_DELAYED(u,spellname)
		if u=="player" then
			if cfg.debugspells then print(cfg.now.." UNIT_SPELLCAST_DELAYED "..spellname) end
			spname, _, _, _, startTime, endTime = UnitCastingInfo(u)
			if not spname then print("spell not found") return end
--			if not startTime then return end
			cfg.casting=spname
			cfg.castStart=startTime / 1e3
			cfg.castEnd=endTime / 1e3
			if lib.onspellupdate then lib.onspellupdate() end
			cfg.Update=true
		end
	end
	
--[[	function Heddevents:UNIT_SPELLCAST_STOP(u,spellname)
		if u=="player" then
			if cfg.debugspells then print(cfg.now.." UNIT_SPELLCAST_STOP "..spellname) end
			cfg.casting=nil
			cfg.castEnd=cfg.now
			cfg.Update=true
		end
	end]]

--[[	function Heddevents:UNIT_SPELLCAST_FAILED(u,spellname)
		if u=="player" then
			if cfg.debugspells then print(cfg.now.." UNIT_SPELLCAST_FAILED "..spellname) end
			cfg.casting=nil
			cfg.castEnd=cfg.now
			cfg.Update=true
		end
	end]]
	
	function Heddevents:UNIT_SPELLCAST_SUCCEEDED(u,spellname)
		if u=="player" and not cfg.res_spells[spellname] then
			if cfg.debugspells then print(cfg.now.." UNIT_SPELLCAST_SUCCEEDED "..spellname) end
			if cfg.ischanneling and cfg.showchannel then
				Heddevents:UNIT_SPELLCAST_CHANNEL_START(u,spellname)
			else
--				print(cfg.now.." UNIT_SPELLCAST_SUCCEEDED "..spellname)
				cfg.casting=nil
				cfg.castEnd=cfg.now
				cfg.ischanneling=nil
				lib.SaveSpell(spellname)
				if lib.onspellupdate then lib.onspellupdate() end
				cfg.Update=true
			end
			if lib.myonspellcastsucceeded then lib.myonspellcastsucceeded(spellname) end
		end
	end

	function Heddevents:UNIT_SPELLCAST_CHANNEL_START(u,spellname)
		if u=="player" and cfg.showchannel then
			if cfg.debugspells then print(cfg.now.." UNIT_SPELLCAST_CHANNEL_START "..spellname) end
			spname, _, _, _, startTime, endTime = UnitChannelInfo(u)
			if not spname then print("spell not found") return end
			cfg.ischanneling=true
			cfg.casting=spname
			cfg.castStart=startTime / 1e3
			cfg.castEnd=endTime / 1e3
			if lib.onspellupdate then lib.onspellupdate() end
			cfg.Update=true
		end
	end
	
	function Heddevents:UNIT_SPELLCAST_CHANNEL_UPDATE(u,spellname)
		if u=="player" and cfg.showchannel then
			if cfg.debugspells then print(cfg.now.." UNIT_SPELLCAST_CHANNEL_UPDATE "..spellname) end
			spname, _, _, _, startTime, endTime = UnitChannelInfo(u)
			if not spname then print("spell not found") return end
			cfg.ischanneling=true
			cfg.casting=spname
			cfg.castStart=startTime / 1e3
			cfg.castEnd=endTime / 1e3
			if lib.onspellupdate then lib.onspellupdate() end
			cfg.Update=true
		end
	end
	
	function Heddevents:UNIT_SPELLCAST_CHANNEL_STOP(u,spellname)
		if u=="player" and cfg.showchannel then
			if cfg.debugspells then print(cfg.now.." UNIT_SPELLCAST_CHANNEL_STOP "..spellname) end
			cfg.ischanneling=nil
			cfg.casting=nil
			cfg.castEnd=cfg.now
			lib.SaveSpell(spellname)
			if lib.onspellupdate then lib.onspellupdate() end
			cfg.Update=true
		end
	end
--[[
	function Heddevents:UNIT_ATTACK(event, unit)
		if lib.myonunitattack then
			lib.myonunitattack(event,unit)
		end
	end
	]]
	function Heddevents:UPDATE_SHAPESHIFT_FORM(...)
		pshape=cfg.shape
		cfg.shape=lib.shape()
		
		if cfg.shape~=pshape then
			if lib.onshapeupdate then lib.onshapeupdate() end
			cfg.Update=true
		end
	end
	
	function Heddevents:PLAYER_ENTERING_WORLD()
		Heddevents:ACTIONBAR_UPDATE_COOLDOWN()
		Heddevents:PLAYER_TARGET_CHANGED()
		Heddevents:UNIT_AURA("player")
		Heddevents:UNIT_POWER_FREQUENT("player")
		lib.createMacros()
		cfg.shape=lib.shape()
		cfg.dpsmode = 'normal'
		if lib.mypew then
			lib.mypew()
		end
		cfg.Update=true
	end
end


local function Hedd_onupdate(self, elapsed)
	lastUpdate = lastUpdate + elapsed
	cfg.now = GetTime()
	
	checkRaidMode()
		
	if(ChatEdit_GetActiveWindow()) then
		lib.setControlValue(1,1,0,0)
	else
		lib.setControlValue(1,0,0,0)
	end
	
	if cfg.Update or lastUpdate > cfg.UpdateTime then --or lib.SpellCasting()

		if lib.myonupdate then
			lib.myonupdate()
		end
		
		if lib.rangecheck then
			lib.rangecheck()
		end
		
		if ((UnitIsDead('target') or not UnitCanAttack('player','target') --[[or not UnitAffectingCombat('target')]]) and not cfg.healingFlag) or cfg.shutdownmode then
			lib.HideAllSpells()
			cfg.emptySpell:Show()
			if cfg.shutdownmode then		
				Heddframe.text:SetText('OFF')
			else
				local txt = ''
				if cfg.mode == 'aoe' then
					txt = 'A'
				else
					txt = 'D/'..lib.getDPSModeText()
				end
				Heddframe.text:SetText('NT/'..txt)
			end
		else
		
			cfg.emptySpell:Hide()
			if cfg.Update then lib.SetPriority() end
			
			-------
			local isboss = (UnitClassification("target") == 'worldboss')
			
	
			local txt = cfg.mode
			if txt == 'dps' then
				txt = txt..'/'..lib.getDPSModeText()
			end
			Heddframe.text:SetText(txt)
		end
			
			
		lastUpdate = 0
		cfg.Update=nil
	end
end

function checkRaidMode()
	if IsInRaid() then
		if cfg.raidmode == 'party' or not cfg.raidmode then
			cfg.raidmode = 'raid'
			lib.resetRaidMode()
		end
	elseif IsInGroup() then
		if cfg.raidmode == 'raid' or not cfg.raidmode then
			cfg.raidmode = 'party'
			lib.resetRaidMode()
		end
	end
end
function Heddtal_onevent(self,event)
	for index,name in pairs(cfg.spells) do
		lib.HideFrame(cfg.spells[index].f)
	end
	Heddframe.text:Hide()
	Heddframe:Hide()
	
	lib.defaults()
	
	Heddframe:UnregisterAllEvents()
	Heddframe:SetScript("OnEvent",nil)
	Heddframe:SetScript("OnUpdate",nil)
	
	cfg.talentname = nil
	
	if Hedd_findclass() then
		lib.basicevents()
		
		lib.setTalentControlFlag()
		
		if lib.classevents[cfg.class] then lib.classevents[cfg.class]() end
		
		cfg.case["end"] = function ()
			if cfg.cmintime~=cfg.maxmintime then return nil end
			lib.UpdateBar(nil)
			return true
		end
		
		lib.UpdateEquipAll()
	
--		if lib.myonequip then lib.myonequip() end
		
		cfg.numcase=0
		for key, value in pairs(cfg.plist) do
			cfg.numcase=cfg.numcase+1
		end
		cfg.numcase=cfg.numcase+1
		
		Heddframe:SetScript("OnEvent", function(cframe, cevent, ...)
			if not cfg.classfound then return end
			--print(cevent)
			Heddevents[cevent](_,...)--_,
		end)

		for k, v in pairs(Heddevents) do
			Heddframe:RegisterEvent(k)
		end
		
		Heddframe:SetScript("OnUpdate", Hedd_onupdate)
		
		if lib.mytal then
			lib.mytal()
		end
		
		
		Heddevents:PLAYER_ENTERING_WORLD()
		Heddframe:Show()
		Heddframe.text:Show()
		
	end
	
end

cfg.notloaded=true
local function Heddframe_pew(self,...)
	if cfg.notloaded then 
		cfg.notloaded=nil
		Heddframe:UnregisterEvent("PLAYER_ENTERING_WORLD")
		Heddframe:RegisterForClicks("AnyUp")
		Heddframe:SetScript("OnClick", function (self, button, down)
		if lib.onclick then 
			lib.onclick(button) 
			lib.onclick(button) 
		end
		end);

		Heddtalents:SetScript("OnEvent",Heddtal_onevent)
		Heddtalents:RegisterEvent("ACTIVE_TALENT_GROUP_CHANGED")
		Heddtalents:RegisterEvent("CHARACTER_POINTS_CHANGED")
		Heddtalents:RegisterEvent("PLAYER_TALENT_UPDATE")
		Heddtal_onevent()
	end
end


Heddframe:SetScript("OnEvent",Heddframe_pew)
Heddframe:RegisterEvent("PLAYER_ENTERING_WORLD")